﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

namespace SearchingComponents.SearchingComponents
{
	public class ComponentsSearcher
	{
		public ComponentsSearcher(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
			this.m_Doc = this.m_Revit.Application.ActiveUIDocument.Document;
		}

		public List<ElementInfo> Search(List<string> searchKeyList, string strCategory, string strMaterial, string strFamilyType)
		{
			List<ElementInfo> list = new List<ElementInfo>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Doc);
			ICollection<Element> collection;
			if (strCategory.CompareTo(ComponentsSearcher.AllCategoryValue) == 0)
			{
				collection = filteredElementCollector.WhereElementIsNotElementType().ToElements();
			}
			else
			{
				Category category = this.m_Doc.Settings.Categories.get_Item(strCategory);
				if (category == null)
				{
					return list;
				}
                collection = filteredElementCollector.WhereElementIsNotElementType().OfCategory((BuiltInCategory)category.Id.IntegerValue).ToElements();
			}
			foreach (Element element in collection)
			{
				if (strFamilyType.CompareTo(ComponentsSearcher.AllFamilySymbolValue) != 0)
				{
					ElementId typeId = element.GetTypeId();
					if (typeId == ElementId.InvalidElementId)
					{
						continue;
					}
					Element element2 = this.m_Doc.GetElement(typeId);
					if (element2.Name.CompareTo(strFamilyType) != 0)
					{
						continue;
					}
				}
				if (strMaterial.CompareTo(ComponentsSearcher.AllMaterialValue) != 0)
				{
					bool flag = false;
					List<Material> materials = RevitVersionFuncs.GetMaterials(element, this.m_Doc);
					foreach (Material material in materials)
					{
						if (material.Name.CompareTo(strMaterial) == 0)
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						continue;
					}
				}
				bool flag2 = false;
				foreach (string value in searchKeyList)
				{
					if (element.Name.IndexOf(value) != -1)
					{
						flag2 = true;
						break;
					}
					ElementId typeId2 = element.GetTypeId();
					if (typeId2 != ElementId.InvalidElementId && typeId2 != null)
					{
						Element element3 = this.m_Doc.GetElement(typeId2);
						if (element3 != null)
						{
							if (element3.Name.IndexOf(value) != -1)
							{
								flag2 = true;
								break;
							}
							if (element3.GetType() == typeof(FamilySymbol))
							{
								FamilySymbol familySymbol = element3 as FamilySymbol;
								if (familySymbol.Family.Name.IndexOf(value) != -1)
								{
									flag2 = true;
									break;
								}
							}
						}
					}
				}
				if (flag2)
				{
					try
					{
						ElementInfo item = new ElementInfo(element, this.m_Doc);
						list.Add(item);
					}
					catch (Exception)
					{
					}
				}
			}
			return list;
		}

		private List<Material> GetMaterialList()
		{
			List<Material> list = new List<Material>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Doc);
			ICollection<Element> collection = filteredElementCollector.OfClass(typeof(Material)).ToElements();
			foreach (Element element in collection)
			{
				Material item = element as Material;
				list.Add(item);
			}
			return list;
		}

		public List<string> GetCategoryRegularList()
		{
			Categories categories = this.m_Doc.Settings.Categories;
			List<string> list = new List<string>();
			foreach (object obj in categories)
			{
				Category category = (Category)obj;
				if (category.Id.IntegerValue != -1)
				{
					List<string> familySymbolRegularList = this.GetFamilySymbolRegularList(category.Name, false);
					if (familySymbolRegularList.Count != 0)
					{
						list.Add(category.Name);
					}
				}
			}
			return list;
		}

		public List<string> GetMaterialRegularList()
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Doc);
			ICollection<Element> collection = filteredElementCollector.OfClass(typeof(Material)).ToElements();
			List<string> list = new List<string>();
			foreach (Element element in collection)
			{
				Material material = element as Material;
				if (material != null)
				{
					list.Add(material.Name);
				}
			}
			return list;
		}

		public List<string> GetFamilySymbolRegularList(string categoryName, bool isInput)
		{
			List<string> list = new List<string>();
			if (categoryName.CompareTo(ComponentsSearcher.AllCategoryValue) == 0)
			{
				return list;
			}
			Category category = null;
			try
			{
				category = this.m_Doc.Settings.Categories.get_Item(categoryName);
				if (category == null)
				{
					return list;
				}
			}
			catch (Exception)
			{
				return list;
			}
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Doc);
            ICollection<Element> collection = filteredElementCollector.WhereElementIsElementType().OfCategory((BuiltInCategory)category.Id.IntegerValue).ToElements();
			foreach (Element element in collection)
			{
				list.Add(element.Name);
			}
			return list;
		}

		public bool IsVisibleInActiveView(ElementId id)
		{
			if (this.m_Doc.ActiveView == null)
			{
				return false;
			}
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Doc, this.m_Doc.ActiveView.Id);
			IList<Element> list = filteredElementCollector.ToElements();
			foreach (Element element in list)
			{
				if (element.Id.IntegerValue.Equals(id.IntegerValue))
				{
					return true;
				}
			}
			return false;
		}

		public void ActiveElementView(ElementId eleId)
		{
			List<ViewPlan> list = new List<ViewPlan>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Doc).OfClass(typeof(ViewPlan)).WhereElementIsNotElementType();
			foreach (Element element in filteredElementCollector)
			{
				ViewPlan item = element as Autodesk.Revit.DB.ViewPlan;
				list.Add(item);
			}
			UIDocument activeUIDocument = this.m_Revit.Application.ActiveUIDocument;
			try
			{
				Element element2 = this.m_Doc.GetElement(eleId);
				if (element2 != null)
				{
					foreach (Autodesk.Revit.DB.ViewPlan viewPlan in list)
					{
						int integerValue = element2.LevelId.IntegerValue;
						if (viewPlan.GenLevel != null && viewPlan.GenLevel.Id.IntegerValue == integerValue)
						{
							activeUIDocument.ActiveView = viewPlan;
							activeUIDocument.RefreshActiveView();
							break;
						}
					}
				}
			}
			catch (Exception)
			{
			}
		}

		public void ZoomToElement(ElementId id)
		{
			try
			{
				UIDocument activeUIDocument = this.m_Revit.Application.ActiveUIDocument;
				activeUIDocument.ShowElements(id);
			}
			catch (Exception)
			{
			}
		}

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public void HighlightShowElements(ElementId id, IntPtr formHandle)
		{
			try
			{
				int wMsg = 7;
				ComponentsSearcher.SendMessage(CmdSearchingComponents._hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
				Element element = this.m_Doc.GetElement(id);
				List<Element> list = new List<Element>();
				list.Add(element);
				RevitVersionFuncs.SetSelection(this.m_Revit.Application.ActiveUIDocument.Selection, list);
				this.m_Revit.Application.ActiveUIDocument.RefreshActiveView();
				ComponentsSearcher.SendMessage(formHandle, wMsg, IntPtr.Zero, IntPtr.Zero);
			}
			catch (Exception)
			{
			}
		}

		private ExternalCommandData m_Revit;

		private Document m_Doc;

		public static string AllCategoryValue = "<全部类别>";

		public static string AllMaterialValue = "<全部材质>";

		public static string AllFamilySymbolValue = "<全部族类型>>";
	}
}
